package com.example.lishop.config

import com.example.lishop.base.MyResponse
import com.example.lishop.util.toString
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException
import org.hibernate.validator.internal.engine.path.PathImpl
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.validation.ObjectError
import org.springframework.web.bind.MethodArgumentNotValidException
import org.springframework.web.bind.annotation.ControllerAdvice
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseBody
import org.springframework.web.servlet.NoHandlerFoundException
import javax.servlet.http.HttpServletRequest
import javax.validation.ConstraintViolation
import javax.validation.ConstraintViolationException


/**
 * Created on 2020/12/28 22:53
 * @author shuguo
 */

@ControllerAdvice
class ControllerExceptionHandler {

    private val logger:Logger = LoggerFactory.getLogger("LiShop Exception ")

    @ExceptionHandler(Exception::class)
    @ResponseBody
    fun exceptionHandler (request:HttpServletRequest, ex:Exception) : MyResponse<Unit> {
        logger.error("Request URL :{}, Exception:{}, Class:{}", request.requestURI, ex.message.toString(), ex.javaClass)

        var code:Int = -1
        var msg = ex.message.toString()

        when (ex) {
            is NoHandlerFoundException -> {//请求地址失效
                code = 404
            }
            is ConstraintViolationException -> {//捕获controller中定义校验规则异常处理
                code = -2
                val str = StringBuilder("接口参数校验错误：")
                val constraintViolations: Set<ConstraintViolation<*>> = ex.constraintViolations
                for (constraintViolation in constraintViolations) {
                    val pathImpl = constraintViolation.propertyPath as PathImpl
                    val paramName = pathImpl.leafNode.name
                    val message = constraintViolation.message
                    str.append("[").append(paramName).append(":").append(message).append("]")
                }
                msg = str.toString()
            }
            is MethodArgumentNotValidException -> {//捕获实体类定义校验规则参数校验异常处理
                code = -3
                val str = StringBuilder("实体类参数校验错误：")
                val all:List<ObjectError> = ex.bindingResult.allErrors
                for (item in all){
                    str.append("[").append(item.objectName).append(":").append(item.defaultMessage.toString()).append("]")
                }
                msg = str.toString()
            }

//        //h5错误页面
//        val mv = ModelAndView()
//        mv.addObject("url", request.requestURI)
//        mv.addObject("exception", e)
//        mv.viewName = "error/error"
//        return mv
        }

        return MyResponse(code, msg, null)

    }
}